﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SF.Utilities
{
    public static class IdCardNumberHelper
    {
        /// <summary>
        /// 转换15位身份证号码为18位
        /// </summary>
        /// <param name="oldIdCard">15位的身份证</param>
        /// <returns>返回18位的身份证</returns>
        public static string ConvertIdCard15To18(string oldIdCard)
        {
            if (oldIdCard.Length != 15) { throw new ArgumentException("传入的身份证号码无效。"); }

            int iS = 0;

            //加权因子常数
            int[] iW = new int[] { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            //校验码常数
            string LastCode = "10X98765432";
            //新身份证号
            string newIdCard;

            newIdCard = oldIdCard.Substring(0, 6);
            //填在第6位及第7位上填上‘1’，‘9’两个数字
            newIdCard += "19";

            newIdCard += oldIdCard.Substring(6, 9);

            //进行加权求和
            for (int i = 0; i < 17; i++)
            {
                iS += int.Parse(newIdCard.Substring(i, 1)) * iW[i];
            }

            //取模运算，得到模值
            int iY = iS % 11;
            //从LastCode中取得以模为索引号的值，加到身份证的最后一位，即为新身份证号。
            newIdCard += LastCode.Substring(iY, 1);
            return newIdCard;
        }

        /// <summary>
        /// 转换18位身份证号码为15位
        /// </summary>
        /// <param name="oldIdCard">18位的身份证</param>
        /// <returns></returns>
        public static string ConvertIdCard18To15(string oldIdCard)
        {
            if (oldIdCard.Length != 18) { throw new ArgumentException("传入的身份证号码无效。"); }

            //先去掉最后一位
            string temp = oldIdCard.Substring(0, oldIdCard.Length - 1);
            //6位地区编码
            string areaCode = temp.Substring(0, 6);
            string otherCode = temp.Substring(8);

            return areaCode + otherCode;
        }

        /// <summary>
        /// 获取另一个版本的身份证号码
        /// 若传入15位，返回18位
        /// 若传入18位，返回15位
        /// </summary>
        /// <param name="idCardNumber">身份证号码</param>
        /// <returns></returns>
        public static string GetOtherVersionIdCardNumber(string idCardNumber)
        {
            return idCardNumber.Length == 15 ? ConvertIdCard15To18(idCardNumber) : ConvertIdCard18To15(idCardNumber);
        }

        /// <summary>
        ///  根据身份证号码计算出年龄
        /// </summary>
        /// <param name="cardID">18位身份证号码</param>
        /// <returns></returns>
        public static int GetAgeByCardID(string cardID)
        {
            int todayYear = DateTime.Now.Year;
            int todayMonth = DateTime.Now.Month;
            int todayDay = DateTime.Now.Day;
            int age = -1;

            string sBirthday = cardID.Substring(6, 4) + "/" + Convert.ToInt32(cardID.Substring(10, 2)) + "/" + Convert.ToInt32(cardID.Substring(12, 2));

            DateTime d = Convert.ToDateTime(sBirthday);
            int birthdayYear = d.Year;
            int birthdayMonth = d.Month;
            int birthdayDay = d.Day;

            if (todayMonth * 1 - birthdayMonth * 1 < 0)
            {
                age = (todayYear * 1 - birthdayYear * 1) - 1;
            }
            else
            {
                if (todayDay - birthdayDay >= 0)
                {
                    age = (todayYear * 1 - birthdayYear * 1);
                }
                else
                {
                    age = (todayYear * 1 - birthdayYear * 1) - 1;
                }
            }
            return age;
        }
    }
}
